home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume6 / tif2ps / part02 < prev    next >
Encoding:
Text File  |  1989-02-03  |  27.8 KB  |  1,036 lines

  1. Path: xanth!nic.MR.NET!csd4.milw.wisc.edu!leah!itsgw!steinmetz!uunet!allbery
  2. From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  3. Newsgroups: comp.sources.misc
  4. Subject: v06i016: tif2ps -- convert TIFF to PostScript (part 2 of 2)
  5. Keywords: TIFF, PostScript, Scanner
  6. Message-ID: <47748@uunet.UU.NET>
  7. Date: 29 Jan 89 20:26:30 GMT
  8. Sender: allbery@uunet.UU.NET
  9. Reply-To: andy@coma.UUCP (Andreas Lampen)
  10. Organization: Technical University of Berlin, Germany (West)
  11. Lines: 1022
  12. Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  13.  
  14. Posting-number: Volume 6, Issue 16
  15. Submitted-by: andy@coma.UUCP (Andreas Lampen)
  16. Archive-name: tif2ps/part02
  17.  
  18. This is part 2 (of 2) of "tif2ps", a program that converts TIFF
  19. (Tag Image File Format - a format for scanned images) to PostScript.
  20.  
  21. If works on UNIX machines and on PCs.
  22.  
  23. Enjoy it,
  24.      Andy
  25.  
  26. ---- Cut here ---- Cut here ---- Cut here ---- Cut here ---- Cut here ----
  27. #! /bin/sh
  28. # This is a shell archive, meaning:
  29. # 1. Remove everything above the #! /bin/sh line.
  30. # 2. Save the resulting text in a file.
  31. # 3. Execute the file with /bin/sh (not csh) to create:
  32. #    scantif.c
  33. #    getopt.c
  34. #    version.c
  35. #    tif2ps.1
  36. #    Shapefile
  37. #    Makefile.PC
  38. # This archive created: Thu Dec 29 20:43:09 1988
  39. export PATH; PATH=/bin:/usr/bin:$PATH
  40. echo shar: "extracting 'scantif.c'" '(18289 characters)'
  41. if test -f 'scantif.c'
  42. then
  43.     echo shar: "will not over-write existing file 'scantif.c'"
  44. else
  45. cat << \SHAR_EOF > 'scantif.c'
  46. /*
  47.  * tif2ps/tifdump -- convert TIFF to PostScript
  48.  *
  49.  * written by:
  50.  * Andreas Lampen, TU-Berlin (andy@coma.UUCP)
  51.  *                 (andy@db0tui62.BITNET)
  52.  *
  53.  * Copyright (C) 1988 by the author.
  54.  * Permission is granted to copy and distribute this program
  55.  * without charge, provided this copyright notice is included
  56.  * in the copy.
  57.  * This Software is distributed on an as-is basis. There will be
  58.  * ABSOLUTELY NO WARRANTY for any part of this software to work
  59.  * correct. In no case will the author be liable to you for damages
  60.  * caused by the usage of this software.
  61.  */
  62.  
  63. /*
  64.  * scantif.c -- read tif-file
  65.  *
  66.  * $Header: scantif.c[1.0] Thu Dec 29 20:10:59 1988 andy@coma published $
  67.  */
  68.  
  69. #include <stdio.h>
  70. #include "defs.h"
  71. #include "tif.h"
  72.  
  73. STATIC IMAGE nullimage = {0, 0, 0, -1L, 0, 0L, 1, 1, 0, 1, 0L, 0L, 1, 1, 0, 0};
  74. STATIC PHMETRIC nullphmetric = { 0, 1, 0, 0, 0 };
  75. STATIC PHYS nullphys = { 0., 0., 2, 1 };
  76. STATIC CONTEXT nullcontext = { '\0', '\0', 0., 0., 0., 0., 1, 1 };
  77.  
  78. #define FIELDSBASE 255
  79. CHAR *fields[] = {
  80.   "SubfileType        ",    /* 255  (ff) */
  81.   "ImageWidth         ",    /* 256 (100) */
  82.   "ImageLength        ",    /* 257 (101) */
  83.   "BitsPerSample      ",    /* 258 (102) */
  84.   "Compression        ",    /* 259 (103) */
  85.   "                   ",    /* 260 (104) unused */
  86.   "                   ",    /* 261 (105) unused */
  87.   "PhotometricInterpr.",    /* 262 (106) */
  88.   "Threshholding      ",    /* 263 (107) */
  89.   "CellWidth          ",    /* 264 (108) */
  90.   "CellLength         ",    /* 265 (109) */
  91.   "FillOrder          ",    /* 266 (10a) */
  92.   "                   ",    /* 267 (10b) unused */
  93.   "                   ",    /* 268 (10c) unused */
  94.   "DocumentName       ",    /* 269 (10d) */
  95.   "ImageDescription   ",    /* 270 (10e) */
  96.   "Make               ",    /* 271 (10f) */
  97.   "Model              ",    /* 272 (110) */
  98.   "StripOffsets       ",    /* 273 (111) */
  99.   "Orientation        ",    /* 274 (112) */
  100.   "                   ",    /* 275 (113) unused */
  101.   "                   ",    /* 276 (114) unused */
  102.   "SamplesPerPixel    ",        /* 277 (115) */
  103.   "RowsPerStrip       ",    /* 278 (116) */
  104.   "StripByteCounts    ",    /* 279 (117) */
  105.   "MinSampleValue     ",    /* 280 (118) */
  106.   "MaxSampleValue     ",    /* 281 (119) */
  107.   "XResolution        ",    /* 282 (11a) */
  108.   "YResolution        ",    /* 283 (11b) */
  109.   "PlanarConfiguration",        /* 284 (11c) */
  110.   "PageName           ",    /* 285 (11d) */
  111.   "XPosition          ",    /* 286 (11e) */
  112.   "YPosition          ",    /* 287 (11f) */
  113.   "FreeOffsets        ",    /* 288 (120) */
  114.   "FreeByteCounts     ",    /* 289 (121) */
  115.   "GrayResponseUnit   ",    /* 290 (122) */
  116.   "GrayResponseCurve  ",    /* 291 (123) */
  117.   "Group3Options      ",    /* 292 (124) */
  118.   "Group4Options      ",    /* 293 (125) */
  119.   "                   ",    /* 294 (126) unused */
  120.   "                   ",    /* 295 (127) unused */
  121.   "ResolutionUnit     ",    /* 296 (128) */
  122.   "PageNumber         ",    /* 297 (129) */
  123.   "                   ",    /* 298 (12a) unused */
  124.   "                   ",    /* 299 (12b) unused */
  125.   "ColorResponseUnit  ",    /* 300 (12c) */
  126.   "ColorResponseCurves",    /* 301 (12d) */
  127. };
  128.  
  129. CHAR *malloc();
  130. VOID logerr();
  131.  
  132. EXPORT INT scantif (filename, pics, tiff)
  133.      CHAR    *filename;
  134.      PICTURE *pics;  /* array of picture buffers -- out */
  135.      TIFF    *tiff;
  136. {
  137.   DATAFILE infile;
  138.   INT      ifdcount=0;
  139.   VOID     EnterPicValue(), GetImageData();
  140.   USHORT   entrycount, wordtemp, nrofentries;
  141.   ULONG    location, dblwordtemp;
  142.   ENTRY    *entry, stripOffsets, stripByteCounts;
  143.  
  144. #ifdef MSDOS
  145.   if ((infile.fdes = fopen (filename, "rb")) == NULL)
  146. #else
  147.   if ((infile.fdes = fopen (filename, "r")) == NULL)
  148. #endif
  149.     { logerr ("scantif", "cannot open input file"); return ERROR; }
  150.  
  151.   /* read the first word, and determine the byte order
  152.    */
  153.   infile.order = INTELTIFF;
  154.   if (GtData (&infile, 0L, 1, TIFFSHORT, (char *)&wordtemp))
  155.     { logerr ("scantif", "can't read first word"); goto error; }
  156.   infile.order = wordtemp;
  157.  
  158.   /* read the 8-byte header
  159.    */
  160.   if (GtTiffHdr (&infile, &(tiff->header)))
  161.     { logerr ("scantif", "can't read header"); goto error; }
  162.  
  163.   location = tiff->header.offset;
  164.          
  165.   /* loop through the IFD's
  166.    */
  167.   do {
  168.     /* if ifd location is 0, quit
  169.      */
  170.     if (location == 0L)
  171.       {
  172.     (VOID) fclose (infile.fdes);
  173.     return OK;
  174.       }
  175.     
  176.     /* read the number of entries
  177.      */
  178.     if (GtData (&infile, location, 1, TIFFSHORT, (char *)&nrofentries))
  179.       { logerr ("scantif", "can't read # of entries"); goto error; }
  180.     tiff->ifdlist[ifdcount].entrycount = nrofentries;
  181.  
  182.     if ((tiff->ifdlist[ifdcount].entrylist = 
  183.      (ENTRY *)malloc (nrofentries * sizeof (ENTRY))) == (ENTRY *)0)
  184.       { logerr ("scantif", "not enough memory"); goto error; }
  185.  
  186.     location += 2;
  187.  
  188.     pics[ifdcount].image = nullimage;
  189.     pics[ifdcount].photoMetric = nullphmetric;
  190.     pics[ifdcount].physWorld = nullphys;
  191.     pics[ifdcount].context = nullcontext;
  192.     
  193.     /* loop through the entries
  194.      */
  195.     for (entrycount = 0; entrycount < nrofentries; entrycount++) {
  196.       /* read the entry, and dump it
  197.        */
  198.       entry = &(tiff->ifdlist[ifdcount].entrylist[entrycount]);
  199.       if (GtTiffEntry (&infile, location, entry))
  200.     goto error;
  201.       /* adjust the current location
  202.        */
  203.       location += (sizeof (ENTRY) - sizeof (CHAR *));
  204.  
  205.       if (entry->tag == STRIPOFFSETS)
  206.     stripOffsets = *entry;
  207.       else
  208.     {
  209.       if (entry->tag == STRIPBYTECOUNTS)
  210.         stripByteCounts = *entry;
  211.       else
  212.         EnterPicValue (entry, &(pics[ifdcount]));
  213.     }
  214.     } /* end of entry loop */
  215.  
  216.     /* read the data */
  217.     GetImageData (&infile, &(pics[ifdcount].image), &stripOffsets, &stripByteCounts);
  218.  
  219.     /* read the location of the next ifd */
  220.     if (GtData(&infile, location, 1, TIFFLONG, (char *)&dblwordtemp))
  221.       { logerr ("scantif", "can't read location of the next ifd"); goto error;}
  222.     location = dblwordtemp;
  223.     ifdcount++;
  224.  
  225.   } while (1); /* end of ifd loop */
  226.  
  227.  error: ;
  228.   (VOID) fclose (infile.fdes);
  229.   return ERROR;
  230. }
  231.  
  232. EXPORT VOID dodump (filename, tiff)
  233.      CHAR *filename;
  234.      TIFF *tiff;
  235. {
  236.   INT    ifdcount=0, i;
  237.   USHORT maxitems, item;
  238.   IFD    *ifdptr;
  239.   CHAR   *bufptr;
  240.  
  241.   printf ("File: %s\n", filename);
  242.  
  243.   /* print header */
  244.   switch (tiff->header.byteorder)
  245.     {
  246.     case INTELTIFF:
  247.       printf ("    Byte Order: INTELTIFF\n");
  248.       break;
  249.     case MOTOROLATIFF:
  250.       printf ("    Byte Order: MOTOROLATIFF\n");
  251.       break;
  252.     default:
  253.       printf ("    Byte Order: ***illegal***\n");
  254.     }
  255.   printf ("    Version: %d\n", tiff->header.version);
  256.   printf ("    Ifd Offset: %d\n", tiff->header.offset);
  257.  
  258.   /* print IFDs */
  259.   do {
  260.     ifdptr = &(tiff->ifdlist[ifdcount]);
  261.     printf ("    IFD Number %d\n", ifdcount);
  262.     printf ("\tNumber of entries: %d\n", ifdptr->entrycount);
  263.     for (i=0; i<ifdptr->entrycount; i++)
  264.       {
  265.     printf ("\t%s (%d) type=%d length=%3d val=",
  266.         (ifdptr->entrylist[i].tag >= 32768) ? "-------------------" :
  267.         fields[ifdptr->entrylist[i].tag-FIELDSBASE],
  268.         ifdptr->entrylist[i].tag, ifdptr->entrylist[i].type,
  269.         ifdptr->entrylist[i].length);
  270.  
  271.     bufptr = ifdptr->entrylist[i].value;
  272.     maxitems = ifdptr->entrylist[i].length;
  273.     switch (ifdptr->entrylist[i].type)
  274.       {
  275.       case TIFFBYTE:
  276.         for (item = 0; item < maxitems; item++)
  277.           printf ("%x", (unsigned)(*bufptr++));
  278.         printf ("\n");
  279.         break;
  280.       case TIFFASCII:
  281.         if (maxitems == 0)
  282.           break;
  283.         printf ("%.*s\n", maxitems, bufptr);
  284.         break;
  285.       case TIFFSHORT:
  286.         for (item = 0; item < maxitems; item++, bufptr += 2)
  287.           printf ("%u ", *((USHORT *)bufptr));
  288.         printf ("\n");
  289.         break;
  290.       case TIFFLONG:
  291.         for (item = 0; item < maxitems; item++, bufptr += 4)
  292.           printf ("%lu ", *((ULONG *)bufptr));
  293.         printf ("\n");
  294.         break;
  295.       case TIFFRATIONAL:
  296.         for (item = 0; item < maxitems; item++) {
  297.           printf ("% lu ", *((ULONG *)bufptr));
  298.           bufptr += 4;
  299.           printf ("%lu ", *((ULONG *)bufptr));
  300.           bufptr += 4;
  301.         }
  302.         printf ("\n");
  303.         break;
  304.       default:
  305.         logerr ("dodump", "internal error");
  306.         break;
  307.       }
  308.       }
  309.   }
  310.   while (tiff->ifdlist[ifdcount++].nextifd);
  311.   printf ("Ok -- that's all ! Bye Bye...\n");
  312. }
  313.  
  314. /**********************************************************************/
  315.  
  316. /*
  317. /* The following six routiones (swap, swaw, GtTiffSizeof, GtData,
  318. /* GtTiffHdr, GtTiffEntry) are not originally written by me.
  319. /* I copied them in a slightli modified form from a "tiffdump"
  320. /* program, I received from Microsoft. There was no copyright
  321. /* notice so I think the code is in the public domain.
  322. /*       Andreas Lampen
  323. /**/
  324.  
  325. /* swap bytes -- overlapping arrays are handled properly
  326.  */
  327.  
  328. LOCAL VOID swab (lpSrc, lpDst, nbytes)
  329.      register CHAR *lpSrc, *lpDst;    /* assumed to be word-aligned */
  330.      USHORT        nbytes;              /* assumed to be even */
  331. {
  332.   register USHORT words;
  333.   union {
  334.     CHAR c[2];
  335.     USHORT w;
  336.   } wrd;
  337.   
  338.   words = nbytes/2;
  339.   
  340.   if (lpDst <= lpSrc || lpDst >= lpSrc + nbytes) {
  341.     for (; words--; lpSrc += 2) {
  342.       wrd.w = *(USHORT *)lpSrc;
  343.       *lpDst++ = *(CHAR *)(wrd.c + 1);    /* W2 doesn't like wrd.c[1] */
  344.       *lpDst++ = *(CHAR *)(wrd.c);
  345.     }
  346.   }
  347.   else {        /* we'll have to go backward */
  348.     lpSrc += nbytes - sizeof(USHORT);
  349.     lpDst += nbytes - 1;
  350.     for (; words--; lpSrc -= 2) {
  351.       wrd.w = *(USHORT *)lpSrc;
  352.       *lpDst-- = *(CHAR *)(wrd.c);
  353.       *lpDst-- = *(CHAR *)(wrd.c + 1);
  354.     }
  355.   }
  356. }
  357.  
  358. /* swap words -- overlapping ranges are handled properly
  359.  */
  360. LOCAL VOID swaw (lpSrc, lpDst, nbytes)
  361.      register CHAR *lpSrc, *lpDst;    /* assumed to be word-aligned */
  362.      USHORT         nbytes;               /* assumed to be multiple of 4 */
  363. {
  364.   register USHORT dwords;
  365.   union {
  366.     CHAR c[4];
  367.     ULONG dw;
  368.   } dwrd;
  369.   
  370.   dwords = nbytes/4;
  371.   
  372.   if (lpDst <= lpSrc || lpDst >= lpSrc + nbytes) {
  373.     for (; dwords--; lpSrc += 4) {
  374.       dwrd.dw = *(ULONG *)lpSrc;
  375.       *lpDst++ = *(CHAR *)(dwrd.c + 3);
  376.       *lpDst++ = *(CHAR *)(dwrd.c + 2);
  377.       *lpDst++ = *(CHAR *)(dwrd.c + 1);
  378.       *lpDst++ = *(CHAR *)(dwrd.c);
  379.     }
  380.   }
  381.   else {        /* we'll have to go backward */
  382.     lpSrc += nbytes - sizeof(ULONG);
  383.     lpDst += nbytes - 1;
  384.     for (; dwords--; lpSrc -= 4) {
  385.       dwrd.dw = *(ULONG *)lpSrc;
  386.       *lpDst-- = *(CHAR *)(dwrd.c);
  387.       *lpDst-- = *(CHAR *)(dwrd.c + 1);
  388.       *lpDst-- = *(CHAR *)(dwrd.c + 2);
  389.       *lpDst-- = *(CHAR *)(dwrd.c + 3);
  390.     }
  391.   }
  392. }
  393.  
  394. LOCAL INT GtTiffSizeof (n, p)
  395.      USHORT n;    /* TIFFBYTE or ... */
  396.      USHORT *p;    /* output */
  397. {
  398.   SHORT err = OK;
  399.   
  400.   switch (n) {
  401.   case TIFFBYTE:
  402.   case TIFFASCII:
  403.     *p = 1;
  404.     break;
  405.   case TIFFSHORT:
  406.     *p = 2;
  407.     break;
  408.   case TIFFLONG:
  409.     *p = 4;
  410.     break;
  411.   case TIFFRATIONAL:
  412.     *p = 8;
  413.     break;
  414.   default:
  415.     *p = 1;
  416.     err = ERROR;
  417.     break;
  418.   }
  419.   return err;
  420. }
  421.  
  422. /* get data -- handles file/table and byte-order problems
  423.  * 64K max
  424.  */
  425. LOCAL INT GtData (pInfile, pos, n, dtype, lpData)
  426.      DATAFILE *pInfile; /* data location - open file or locked-down table */
  427.      ULONG  pos;       /* file/table position, with respect to its beginning */
  428.      USHORT n;           /* number of data elements to read */
  429.      USHORT dtype;     /* data type: TIFFSHORT, etc */
  430.      CHAR   *lpData;   /* where to put the data */
  431. {
  432.   INT    err;
  433.   USHORT tsize, BytesToRead;
  434.  
  435.   /* read the data
  436.    */
  437.   if (err = GtTiffSizeof (dtype, &tsize))
  438.     return err;
  439.  
  440.   BytesToRead = tsize * n;
  441.   if (err = fseek (pInfile->fdes, (long) pos, 0))
  442.     { logerr ("GtData", "fseek error"); return ERROR; }
  443.  
  444.   if ((fread (lpData, 1, (INT)BytesToRead, pInfile->fdes)) == 0)
  445.     { logerr ("GtData", "fread error"); return ERROR; }
  446.  
  447.   /* change the byte order, if necessary
  448.    */
  449. #ifdef MOTOROLA
  450.   if (pInfile->order == INTELTIFF) {
  451. #else
  452.   if (pInfile->order == MOTOROLATIFF) {
  453. #endif
  454.     if (dtype == TIFFSHORT)
  455.       swab (lpData, lpData, BytesToRead);
  456.     else if (dtype == TIFFLONG)
  457.       swaw (lpData, lpData, BytesToRead);
  458.     else if (dtype == TIFFRATIONAL)
  459.       swaw (lpData, lpData, BytesToRead);
  460.   }
  461.  
  462.   return OK;
  463. }
  464.   
  465. /* get TIFF 8-byte header
  466.  * currently only probably portable.  depends somewhat on compiler's 
  467.  * structure organization.
  468.  */
  469. LOCAL INT GtTiffHdr (pInfile, pHdr)
  470.      DATAFILE *pInfile;
  471.      HEADER *pHdr;
  472. {
  473.   SHORT err;
  474.   
  475.   /* get the first 2 words
  476.    */
  477.   if (err = GtData (pInfile, (ULONG) 0, 2, TIFFSHORT, (CHAR *)&pHdr->byteorder))
  478.     { logerr ("GtTiffHdr", "A"); return err; }
  479.   
  480.   /* get the double word (IFD offset)
  481.    */
  482.   if (err = GtData (pInfile, (ULONG)4, 1, TIFFLONG, (CHAR *)&pHdr->offset))
  483.     { logerr ("GtTiffHdr", "B"); return err; }
  484.  
  485.   return OK;
  486. }
  487.  
  488. /* get TIFF directory entry
  489.  */
  490. LOCAL INT GtTiffEntry (pInfile, EntryOffset, pDe)
  491.      DATAFILE    *pInfile;
  492.      ULONG    EntryOffset;
  493.      ENTRY    *pDe;
  494. {
  495.   SHORT  err;
  496.   USHORT tsize, BytesToRead, maxitems;
  497.   ULONG  valpos;
  498.   
  499.   /* get the 2 words beginning with deTag
  500.    */
  501.   if (err = GtData (pInfile, EntryOffset, 2, TIFFSHORT, (CHAR *)&pDe->tag))
  502.     return err;
  503.  
  504.   /* get the 2 dwords, beginning with deLength
  505.    */
  506.   if (err = GtData (pInfile, EntryOffset + 4L, 2, TIFFLONG,(CHAR *)&pDe->length))
  507.     return err;
  508.  
  509.   /* get value
  510.    */
  511.   if (err = GtTiffSizeof (pDe->type, &tsize))
  512.     return err;
  513.  
  514.   if ((BytesToRead = tsize * pDe->length) == 0)
  515.     return OK; /* no need to read data */
  516.  
  517.   if ((pDe->value = malloc (BytesToRead)) == (CHAR *)0)
  518.     { logerr ("GtTiffEntry", "not enough memory"); return err; }
  519.  
  520.   maxitems = (USHORT)(pDe->length);
  521.   /* careful here: we can't just use valoffset to grab data out of, since
  522.    * may already have been byte-reversed!
  523.    */
  524.   if (BytesToRead <= 4)
  525.     valpos = EntryOffset + 8L;    /* valoffset starts on byte 8, wit de */
  526.   else
  527.     valpos = pDe->valoffset;
  528.   if (err = GtData (pInfile, valpos, maxitems, pDe->type, pDe->value))
  529.     return err;
  530.  
  531.   return OK;
  532. }
  533.  
  534. LOCAL VOID EnterPicValue (entry, picture)
  535.      ENTRY   *entry;
  536.      PICTURE *picture;
  537. {
  538.   CHAR *bufptr;
  539.   ULONG num, denom;
  540.   SHORT i;
  541.  
  542.   switch (entry->tag)
  543.     {
  544.     case SUBFILETYPE:
  545.       picture->image.subfileType = *((USHORT *)entry->value);
  546.       break;
  547.     case IMAGEWIDTH:
  548.       picture->image.imWidth = *(USHORT *)entry->value;
  549.       break;
  550.     case IMAGELENGTH:
  551.       picture->image.imLength = *(USHORT *)entry->value;
  552.       break;
  553.     case ROWSPERSTRIP:
  554.       picture->image.rowsPerStrip = *(ULONG *)entry->value;
  555.       break;
  556.     case SAMPLESPERPIXEL:
  557.       /* ignored */
  558.       break;
  559.     case BITSPERSAMPLE:
  560.       picture->image.bitsPerSample = *(USHORT *)entry->value;
  561.       break;
  562.     case PLANARCONFIGURATION:
  563.       picture->image.planConf = *(USHORT *)entry->value;
  564.       break;
  565.     case COMPRESSION:
  566.       picture->image.compression = *(USHORT *)entry->value;
  567.       break;
  568.     case GROUP3OPTIONS:
  569.       picture->image.gr3Options = *(ULONG *)entry->value;
  570.       break;
  571.     case GROUP4OPTIONS:
  572.       picture->image.gr4Options = *(ULONG *)entry->value;
  573.       break;
  574.     case FILLORDER:
  575.       picture->image.fillOrder = *(USHORT *)entry->value;
  576.       break;
  577.     case THRESHHOLDING:
  578.       picture->image.threshholding = *(USHORT *)entry->value;
  579.       break;
  580.     case CELLWIDTH:
  581.       picture->image.cellWidth = *(USHORT *)entry->value;
  582.       break;
  583.     case CELLLENGTH:
  584.       picture->image.cellLength = *(USHORT *)entry->value;
  585.       break;
  586.     case MINSAMPLEVALUE:
  587.       picture->photoMetric.minSampleValue = *(USHORT *)entry->value;
  588.       break;
  589.     case MAXSAMPLEVALUE:
  590.       picture->photoMetric.maxSampleValue = *(USHORT *)entry->value;
  591.       break;
  592.     case PHOTOMETRICINTERPR:
  593.       picture->photoMetric.photometInterpr = *(USHORT *)entry->value;
  594.       break;
  595.     case GRAYRESPONSEUNIT:
  596.       picture->photoMetric.grayResponseUnit = *(USHORT *)entry->value;
  597.       break;
  598.     case GRAYRESPONSECURVE:
  599.       bufptr = entry->value;
  600.       picture->photoMetric.grayResponseCurve = 
  601.     (USHORT *)malloc ((UINT)(entry->length+1) * sizeof (USHORT)); 
  602.       for (i=0; i < entry->length; i++, bufptr += 2)
  603.     picture->photoMetric.grayResponseCurve[i] = *(USHORT *)bufptr;
  604.       picture->photoMetric.grayResponseCurve[entry->length] = -1;
  605.       break;
  606.     case XRESOLUTION:
  607.       num = *(ULONG *)entry->value;
  608.       bufptr = entry->value+4;
  609.       denom = *(ULONG *)bufptr;
  610.       picture->physWorld.xRes = (DOUBLE)num/(DOUBLE)denom;
  611.       break;
  612.     case YRESOLUTION:
  613.       num = *(ULONG *)entry->value;
  614.       bufptr = entry->value+4;
  615.       denom = *(ULONG *)bufptr;
  616.       picture->physWorld.yRes = (DOUBLE)num/(DOUBLE)denom;
  617.       break;
  618.     case RESOLUTIONUNIT:
  619.       picture->physWorld.resUnit = *(USHORT *)entry->value;
  620.       break;
  621.     case ORIENTATION:
  622.       picture->physWorld.orientation = *(USHORT *)entry->value;
  623.       break;
  624.     case DOCUMENTNAME:
  625.       picture->context.docName = (CHAR *) entry->value;
  626.       break;
  627.     case PAGENAME:
  628.       picture->context.pageName = (CHAR *) entry->value;
  629.       break;
  630.     case XPOSITION:
  631.       num = *(ULONG *)entry->value;
  632.       bufptr = entry->value+4;
  633.       denom = *(ULONG *)bufptr;
  634.       picture->context.xPos = (DOUBLE)num/(DOUBLE)denom;
  635.       break;
  636.     case YPOSITION:
  637.       num = *(ULONG *)entry->value;
  638.       bufptr = entry->value+4;
  639.       denom = *(ULONG *)bufptr;
  640.       picture->context.yPos = (DOUBLE)num/(DOUBLE)denom;
  641.       break;
  642.     case PAGENUMBER:
  643.       picture->context.pageNo = *(USHORT *)entry->value;
  644.       bufptr = entry->value+2;
  645.       picture->context.noOfPages = *(USHORT *)bufptr;
  646.       break;
  647.     }
  648. }
  649.  
  650. LOCAL VOID GetImageData (infile, image, stripOffsets, stripByteCounts)
  651.      DATAFILE *infile;
  652.      IMAGE    *image;
  653.      ENTRY    *stripOffsets, *stripByteCounts;
  654. {
  655.   ULONG offset;
  656.  
  657.   if (stripOffsets->length != 1)
  658.     { logerr ("GetImageData", "cannot handle multiple strips"); return; }
  659.  
  660.   if ((image->strips = (STRIP *)malloc (2 * sizeof (STRIP))) == (STRIP *)0)
  661.     { logerr ("GetImageData", "not enough memory"); return; }
  662.  
  663.   image->strips[0].byteCount = *(ULONG *)stripByteCounts->value;
  664.   offset = *(ULONG *)stripOffsets->value;
  665.  
  666.   if (fseek (infile->fdes, (LONG) offset, 0) == ERROR)
  667.     { logerr ("GetImageData", "fseek error"); return; }
  668.  
  669.   if ((image->strips[0].data = 
  670.        malloc ((UINT)image->strips[0].byteCount)) == (CHAR *)0)
  671.     { logerr ("GetImageData", "not enough memory"); return; }
  672.  
  673.   if (fread (image->strips[0].data, sizeof (CHAR),
  674.          (INT)image->strips[0].byteCount, infile->fdes) == 0)
  675.     { logerr ("GetImageData", "fread error"); return; }
  676.  
  677.   image->strips[1].byteCount = 0;
  678.   image->strips[1].data = (char *)0;
  679. }
  680. SHAR_EOF
  681. if test 18289 -ne "`wc -c < 'scantif.c'`"
  682. then
  683.     echo shar: "error transmitting 'scantif.c'" '(should have been 18289 characters)'
  684. fi
  685. fi
  686. echo shar: "extracting 'getopt.c'" '(1640 characters)'
  687. if test -f 'getopt.c'
  688. then
  689.     echo shar: "will not over-write existing file 'getopt.c'"
  690. else
  691. cat << \SHAR_EOF > 'getopt.c'
  692. /*
  693.  *    I got this off net.sources from Henry Spencer.
  694.  *    It is a public domain getopt(3) like in System V.
  695.  *
  696.  *    I made some minor modifications while porting it to MS-DOS.
  697.  *        andy@coma
  698.  */
  699. #include <stdio.h>
  700. #include <string.h>
  701.  
  702. #define    ARGCH    (int)':'
  703. #define BADCH     (int)'?'
  704. #define EMSG     ""
  705. #define    ENDARGS  "--"
  706.  
  707. /*
  708.  * get option letter from argument vector
  709.  */
  710. int    optind = 1,        /* index into parent argv vector */
  711.     optopt;            /* character checked for validity */
  712. char    *optarg;        /* argument associated with option */
  713.  
  714. #define tell(s)    fputs(*nargv,stderr);fputs(s,stderr); \
  715.         (void)fputc(optopt,stderr);(void)fputc('\n',stderr); \
  716.                 return(BADCH);
  717.  
  718. int getopt(nargc,nargv,ostr)
  719. int    nargc;
  720. char    **nargv,
  721.     *ostr;
  722. {
  723.     static char    *place = EMSG;    /* option letter processing */
  724.     register char    *oli;        /* option letter list index */
  725.  
  726.     if(!*place) {            /* update scanning pointer */
  727.         if(optind >= nargc || *(place = nargv[optind]) != '-' || !*++place) return(EOF);
  728.         if (*place == '-') {    /* found "--" */
  729.             ++optind;
  730.             return(EOF);
  731.         }
  732.     }                /* option letter okay? */
  733.     if ((optopt = (int)*place++) == ARGCH || !(oli = strchr (ostr,optopt))) {
  734.         if(!*place) ++optind;
  735.         tell(": illegal option -- ");
  736.     }
  737.     if (*++oli != ARGCH) {        /* don't need argument */
  738.         optarg = NULL;
  739.         if (!*place) ++optind;
  740.     }
  741.     else {                /* need an argument */
  742.         if (*place) optarg = place;    /* no white space */
  743.         else if (nargc <= ++optind) {    /* no arg */
  744.             place = EMSG;
  745.             tell(": option requires an argument -- ");
  746.         }
  747.          else optarg = nargv[optind];    /* white space */
  748.         place = EMSG;
  749.         ++optind;
  750.     }
  751.     return(optopt);            /* dump back option letter */
  752. }
  753. SHAR_EOF
  754. if test 1640 -ne "`wc -c < 'getopt.c'`"
  755. then
  756.     echo shar: "error transmitting 'getopt.c'" '(should have been 1640 characters)'
  757. fi
  758. fi
  759. echo shar: "extracting 'version.c'" '(129 characters)'
  760. if test -f 'version.c'
  761. then
  762.     echo shar: "will not over-write existing file 'version.c'"
  763. else
  764. cat << \SHAR_EOF > 'version.c'
  765. #include "defs.h"
  766. CHAR *version () {
  767.   STATIC CHAR ConfID[] =  "1.0 (Thu Dec 29 20:05:10 1988 by andy@coma)";
  768.   return ConfID;
  769. }
  770. SHAR_EOF
  771. if test 129 -ne "`wc -c < 'version.c'`"
  772. then
  773.     echo shar: "error transmitting 'version.c'" '(should have been 129 characters)'
  774. fi
  775. fi
  776. echo shar: "extracting 'tif2ps.1'" '(2661 characters)'
  777. if test -f 'tif2ps.1'
  778. then
  779.     echo shar: "will not over-write existing file 'tif2ps.1'"
  780. else
  781. cat << \SHAR_EOF > 'tif2ps.1'
  782. ...
  783. ... tif2ps/tifdump -- convert TIFF to PostScript
  784. ...
  785. ... written by:
  786. ... Andreas Lampen, TU-Berlin (andy@coma.UUCP)
  787. ...                 (andy@db0tui62.BITNET)
  788. ...
  789. ... Copyright (C) 1988 by the author.
  790. ... Permission is granted to copy and distribute this program
  791. ... without charge, provided this copyright notice is included
  792. ... in the copy.
  793. ... This Software is distributed on an as-is basis. There will be
  794. ... ABSOLUTELY NO WARRANTY for any part of this software to work
  795. ... correct. In no case will the author be liable to you for damages
  796. ... caused by the usage of this software.
  797. ...
  798. .TH TIF2PS 1
  799. .SH NAME
  800. tif2ps, tifdump \- convert TIFF files to PostScript
  801. .SH SYNOPSIS
  802. .B tif2ps
  803. .RB [ \-h
  804. .IR height ]
  805. .RB [ \-s ]
  806. .IR scalefactor ]
  807. .RB [ \-v ]
  808. .RB [ \-x
  809. .IR x-offset ]
  810. .RB [ \-y
  811. .IR y-offset ]
  812. file1 ...
  813. .LP
  814. .B tifdump 
  815. .RB [ \-v ]
  816. file1 ...
  817. .SH DESCRIPTION
  818. \fITif2ps\fR converts a TIFF file to PostScript, and writes the result
  819. to standard output.
  820. \fITif2ps\fR recognizes the following options:
  821. .TP
  822. .BI \-h " height"
  823. defines the height of the resulting picture (in inches).
  824. .TP
  825. .BI \-s " scalefactor"
  826. scales the picture by the given factor (eg. \fI\-s 2\fR produces a
  827. double height / double width picture).
  828. \fBNote:\fR only one of \fI\-h\fR and \fI\-s\fR can be given.
  829. .TP
  830. .BI \-v
  831. prints the version identification of \fItif2ps\fR.
  832. No PostScript output is produced
  833. .TP
  834. .BI \-x " x-offset"
  835. defines the horizontal offset of the picture relative to the lower
  836. left corner of the printed page.
  837. .TP
  838. .BI \-y " y-offset"
  839. defines the vertical offset of the picture relative to the lower
  840. left corner of the printed page.
  841. .LP
  842. \fITifdump\fR produces a human readable dump of the given TIFF-files.
  843. The result is written to standard output.
  844. .SH BUGS
  845. This version of \fItif2ps\fR has not been tested very extensively yet.
  846. So don't be too angry if it produces core dumps or incorrect PostScript
  847. files.
  848. In that case, please drop a short error report to the author.
  849. .PP
  850. Gray scale images look better when using the PostScript default
  851. grayscale instead of the grayscale given in the TIFF file.
  852. I do not know why. The actual version always sets the grayscale
  853. given in the TIFF-file. You can change that either by editing the
  854. source or by deleting three lines in the PostScript output.
  855. You find these three lines behind the first \fCgsave\fR call 
  856. and they look like
  857. .br
  858. .in 2i
  859. \fC{ 15 mul round ...
  860. .br
  861. \&...
  862. .br
  863. \&... } settransfer\fR
  864. .br
  865. .PP
  866. Data compression is not yet supported.
  867. .PP
  868. The PC version does only support TIFF files that contain at most
  869. 45000 bytes of image data.
  870. .SH AUTHOR
  871. Andreas Lampen, TU Berlin
  872. .sp
  873. .ta 0.7i 
  874. UUCP:    unido!coma!andy
  875. .br
  876. BITNET:    andy@db0tui62
  877. SHAR_EOF
  878. if test 2661 -ne "`wc -c < 'tif2ps.1'`"
  879. then
  880.     echo shar: "error transmitting 'tif2ps.1'" '(should have been 2661 characters)'
  881. fi
  882. fi
  883. echo shar: "extracting 'Shapefile'" '(1942 characters)'
  884. if test -f 'Shapefile'
  885. then
  886.     echo shar: "will not over-write existing file 'Shapefile'"
  887. else
  888. cat << \SHAR_EOF > 'Shapefile'
  889. #
  890. # Shapefile for tif2ps
  891. #
  892. # $Header: Shapefile[1.0] Thu Dec 29 20:10:12 1988 andy@coma published $
  893.  
  894. INSTALDIR = /usr/local
  895. MANINSTALDIR = /usr/localman/man1
  896. INSTALNAME = bin
  897. INSTALGROUP = bin
  898.  
  899. #
  900. # Default settings
  901. #
  902. SYSTEM = unix
  903. QUALITY = debug
  904.  
  905. #
  906. # Components
  907. #
  908. SOURCE = tif2ps.c scantif.c genps.c getopt.c
  909. INCLUDE = tif.h defs.h
  910. VERSION = version
  911. OBJECTS = tif2ps.o scantif.o genps.o $(VERSION).o
  912. COMPONENTS = $(SOURCE) $(INCLUDE)\
  913.      tif2ps.1 README Makefile Makefile.PC Shapefile
  914.  
  915. #
  916. #% RULE-SECTION
  917. #
  918. testrule:
  919.     *, attr (state, busy);
  920.     *, attrmax (version), msg (used saved version of $+.).
  921.  
  922. relrule:
  923.     *, attr (state, published), attrmax (version).
  924. #
  925. #% END-RULE-SECTION
  926. #
  927. #% VARIANT-SECTION
  928. #
  929. vclass system ::= (unix, unixmotorola, msdos)
  930. vclass quality ::= (debug, final)
  931.  
  932. unix:
  933.     vflags = -DUNIX
  934. unixmotorola:
  935.     vflags = -DUNIX -DMOTOROLA
  936. msdos:
  937.     vflags = -DMSDOS
  938. debug:
  939.     CFLAGS = -g -DDEBUG
  940.     LDFLAGS = -g
  941. final:
  942.     CFLAGS = -O
  943.     LDFLAGS = -s
  944. #
  945. #% END-VARIANT-SECTION
  946. #
  947.  
  948. tif2ps: testrule +$(SYSTEM) +$(QUALITY) prog
  949.  
  950. install: relrule +$(SYSTEM) +$(QUALITY) prog
  951.     install -c -o bin -g bin -m 644 tif2ps.1 $(MANINSTALDIR); \
  952.     install -c -o bin -g bin -m 755 tif2ps $(INSTALDIR); \
  953.     rm -f $(INSTALDIR)/tifdump; \
  954.     ln $(INSTALDIR)/tif2ps $(INSTALDIR)/tifdump
  955.  
  956. release:
  957.     @rm -f $(VERSION).c; \
  958.     echo '#include "defs.h"' > $(VERSION).c ; \
  959.     echo 'CHAR *$Shapefile () {' >> $(VERSION).c ; \
  960.     echo '  STATIC CHAR ConfID[] =  "$1.0 ($Thu Dec 29 20:05:43 1988 by $andy@coma$)";' >> $(VERSION).c ; \
  961.     echo '  return ConfID;' >> $(VERSION).c ; \
  962.     echo '}' >> $(VERSION).c
  963.     sbmt -fq $(VERSION).c; \
  964.     sbmt -q $(COMPONENTS)
  965.     @echo don\'t forget to execute \'shape install\'
  966.  
  967. prog: $(OBJECTS)
  968.     $(CC) -o tif2ps $(LDFLAGS) $(OBJECTS) -lm; \
  969.     rm -f tifdump; \
  970.     ln tif2ps tifdump
  971.  
  972. $(OBJECTS): $(INCLUDE)
  973.  
  974. #
  975. # Miscellaneous targets
  976. #
  977.  
  978. tags: $(SOURCE)
  979.     /usr/local/etags $(SOURCE)
  980.  
  981. xref: $(SOURCE)
  982.     /usr/ucb/ctags -w -x $(SOURCE) > xref
  983.  
  984. clean :
  985.     rm $(OBJECTS)
  986.  
  987. SHAR_EOF
  988. if test 1942 -ne "`wc -c < 'Shapefile'`"
  989. then
  990.     echo shar: "error transmitting 'Shapefile'" '(should have been 1942 characters)'
  991. fi
  992. fi
  993. echo shar: "extracting 'Makefile.PC'" '(502 characters)'
  994. if test -f 'Makefile.PC'
  995. then
  996.     echo shar: "will not over-write existing file 'Makefile.PC'"
  997. else
  998. cat << \SHAR_EOF > 'Makefile.PC'
  999. #
  1000. # Makefile for tif2ps (MS-DOS version)
  1001. #
  1002.  
  1003. CFLAGS = /D MSDOS /FPi /AL
  1004.  
  1005. tif2ps.obj: tif2ps.c tif.h defs.h
  1006.     CL /c $(CFLAGS) tif2ps.c
  1007.  
  1008. scantif.obj: scantif.c tif.h defs.h
  1009.     CL /c $(CFLAGS) scantif.c
  1010.  
  1011. genps.obj: genps.c tif.h defs.h
  1012.     CL /c $(CFLAGS) genps.c
  1013.  
  1014. getopt.obj : getopt.c
  1015.     CL /c $(CFLAGS) getopt.c
  1016.  
  1017. version.obj : version.c defs.h
  1018.     CL /c $(CFLAGS) version.c
  1019.  
  1020. tif2ps.exe: tif2ps.obj scantif.obj genps.obj getopt.obj version.obj
  1021.     CL $(CFLAGS) tif2ps.obj scantif.obj genps.obj getopt.obj version.obj
  1022.  
  1023. SHAR_EOF
  1024. if test 502 -ne "`wc -c < 'Makefile.PC'`"
  1025. then
  1026.     echo shar: "error transmitting 'Makefile.PC'" '(should have been 502 characters)'
  1027. fi
  1028. fi
  1029. exit 0
  1030. #    End of shell archive
  1031.  
  1032. -- 
  1033. Andreas Lampen, TU Berlin
  1034. UUCP:   andy@coma (unido!coma!andy)
  1035. BITNET: andy@db0tui62
  1036.